import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ColorPickerDirective } from './color-picker.directive';
import { ColorPickerModule } from './color-picker.module';

@Component({
  template: `
    <div
      class="aui-color"
      [style.background]="color"
      lv-color-picker
      [lvColorPickerHeader]="lvColorPickerHeader"
      [lvColorPickerFooter]="lvColorPickerFooter"
      [lvColorPickerShowArrow]="lvColorPickerShowArrow"
      [lvColorPickerShowColorText]="lvColorPickerShowColorText"
      [(lvColorPickerValue)]="color"
      (lvColorPickerValueChange)="valueChange($event)"
    ></div>
  `,
  styles: [
    `
      .aui-color {
        width: 32px;
        height: 32px;
      }
    `,
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestColorPickerComponent {
  @Input() lvColorPickerHeader = '';
  @Input() lvColorPickerFooter = '';
  @Input() lvColorPickerShowArrow = true;
  @Input() lvColorPickerFormat = 'hex';
  @Input() lvColorPickerShowColorText = true;

  color: string = '#ff0000';

  valueChange(e) {}
}

describe('ColorPickerComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [ColorPickerDirective, TestColorPickerComponent],
        imports: [ColorPickerModule, NoopAnimationsModule],
        teardown: { destroyAfterEach: false },
      }).compileComponents();
    })
  );

  describe('render correctly', () => {
    let component: TestColorPickerComponent;
    let fixture: ComponentFixture<TestColorPickerComponent>;

    const getColorPicker = (param?) => {
      if (param) {
        for (const [key, value] of Object.entries(param)) {
          component[key] = value;
        }
      }
      fixture.detectChanges();
      const button = fixture.nativeElement.querySelector('.aui-color');
      button.dispatchEvent(new Event('click'));
      tick(500);
      fixture.detectChanges();
      tick(500);
      return document.querySelector('.lv-color-picker-panel');
    };

    beforeEach(() => {
      fixture = TestBed.createComponent(TestColorPickerComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });

    it('with default', fakeAsync(() => {
      const colorPicker = getColorPicker();
      expect(colorPicker).toMatchSnapshot();
    }));

    it('with lvColorPickerHeader/lvColorPickerFooter', fakeAsync(() => {
      const colorPicker = getColorPicker({ lvColorPickerHeader: '拾色器', lvColorPickerFooter: '拾色器底部' });
      expect(colorPicker).toMatchSnapshot();
    }));

    it('without lvColorPickerShowArrow', fakeAsync(() => {
      const colorPicker = getColorPicker({ lvColorPickerShowArrow: false });
      expect(colorPicker.querySelector('.lv-popover-arrow')).toBeNull();
    }));

    it('with lvColorPickerShowColorText', fakeAsync(() => {
      const colorPicker = getColorPicker();
      const input: HTMLInputElement = colorPicker.querySelector('.lv-color-picker-text');
      expect(input.value).toEqual(component.color);
    }));

    it('without lvColorPickerShowColorText', fakeAsync(() => {
      const colorPicker = getColorPicker({ lvColorPickerShowColorText: false });
      const input: HTMLInputElement = colorPicker.querySelector('.lv-color-picker-text');
      expect(input).toBeNull();
    }));
  });

  describe('should work', () => {
    let component: TestColorPickerComponent;
    let fixture: ComponentFixture<TestColorPickerComponent>;

    const getColorPicker = (param?) => {
      if (param) {
        for (const [key, value] of Object.entries(param)) {
          component[key] = value;
        }
      }
      fixture.detectChanges();
      const button = fixture.nativeElement.querySelector('.aui-color');
      button.dispatchEvent(new Event('click'));
      tick(500);
      fixture.detectChanges();
      tick(500);
      return document.querySelector('.lv-color-picker-panel');
    };

    beforeEach(() => {
      fixture = TestBed.createComponent(TestColorPickerComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });

    it('with valueChange', fakeAsync(() => {
      jest.spyOn(component, 'valueChange');
      const colorPicker = getColorPicker();
      const picker = colorPicker.querySelector('.lv-color-picker-palette');
      picker.dispatchEvent(new Event('mousedown'));
      tick(500);
      fixture.detectChanges();
      expect(component.valueChange).toBeCalled();
    }));
  });
});
